//  Inside Microsoft Exchange 2007 Web Services 
//  Chapter 11
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.  
//  All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using ProxyHelpers.EWS;

namespace FindRelatedTasks
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential("username", "password", "domain");

            // TODO:  You need to pass in an id of a task that you want to find related tasks for.
            //
            //FindRelatedTasks(binding, yourTaskId);
        }
        
        /// <summary>
        /// Finds the related tasks for a given task
        /// </summary>
        /// <param name="binding">Binding to use for EWS calls</param>
        /// <param name="taskId">The Id of the task to find</param>
        /// <returns>The matching items</returns>
        /// 
        public static ItemType[] FindRelatedTasks(
                               ExchangeServiceBinding binding,
                               ItemIdType taskId)
        {
            // First, retrieve the internet message id (0x1035) for the supplied task 
            // by supplying the extended field property path in the response shape
            //
            PathToExtendedFieldType messageIdProp = new PathToExtendedFieldType();
            messageIdProp.PropertyTag = "0x1035";
            messageIdProp.PropertyType = MapiPropertyTypeType.String;

            ItemResponseShapeType responseShape = new ItemResponseShapeType(
                                        DefaultShapeNamesType.IdOnly,
                                        messageIdProp);

            // Retrieve the task item and read off the internet message id which is the
            // only extended property that we requested, so it will be the first item
            // in the array.
            //
            ItemType taskItem = EWSHelpers.SimpleGetItem(binding, taskId, responseShape);
            string messageId = (string)taskItem.ExtendedProperty[0].Item;

            // Now prepare our FindItem call and restrict on the internet message id 
            // value...
            //
            RestrictionType restriction = new RestrictionType();
            IsEqualToType equalsMessageId = new IsEqualToType();
            equalsMessageId.Item = messageIdProp;
            equalsMessageId.FieldURIOrConstant = new FieldURIOrConstantType();
            ConstantValueType messageIdConstantValue = new ConstantValueType();
            messageIdConstantValue.Value = messageId;
            equalsMessageId.FieldURIOrConstant.Item = messageIdConstantValue;

            restriction.Item = equalsMessageId;
            FindItemType findRequest = new FindItemType();
            findRequest.ItemShape = new
                   ItemResponseShapeType(DefaultShapeNamesType.Default);

            // Look in the default tasks folder.
            //
            findRequest.ParentFolderIds = new BaseFolderIdType[] { 
                new DistinguishedFolderIdType(DistinguishedFolderIdNameType.tasks) };
            findRequest.Restriction = restriction;
            findRequest.Traversal = ItemQueryTraversalType.Shallow;

            // Make the actual FindItem call
            //
            FindItemResponseType findResponse = binding.FindItem(findRequest);
            FindItemResponseMessageType findMessage =
                 findResponse.ResponseMessages.Items[0] as FindItemResponseMessageType;

            if (findMessage.ResponseCode != ResponseCodeType.NoError)
            {
                throw new Exception("Find failed with response code: " +
                         findMessage.ResponseCode.ToString());
            }
            ItemType[] items = (findMessage.RootFolder.Item as
                     ArrayOfRealItemsType).Items;
            return items;
        }
    }
}
